/*
	DriverStack.java
	Autor: Jennifer Pamela Valdez Cabrera
	Carne: 10189
	Fecha de entrega: 21 de Julio de 2011
	Descripcion: Es un programa que utiliza Stacks para poder calcular expresiones en Postfix
*/

import java.util.*;

public class DriverStack {
  public static void main(String[] args) {
	
	//variables
	Scanner readln = new Scanner(System.in);
        Pila<Double> miStack = new Pila<Double>();
	String expresion;
	String[] expre;
	boolean error;
	double numero;
	
	instrucciones();
	
	// +-- Pedir la expresion hasta que este ingresada correctamente, y separarla con espacios para luego hacer la operacion --+
	do{
		System.out.println("\n Ingrese la expresion que desea calcular: ");
		expresion = readln.nextLine();
		error = false;
		
		// +-- se recorre la expresion para verificar que contenga solo numeros o parametros + - * / .
		for (int i=0; i < expresion.length() && !error; i++){
			char c = expresion.charAt(i);
			if ((c == '+') || (c == '-') || (c == '*') || (c == '/')){			// si encuentra un operando lo separa con espacios para poder hacer el split
				expresion = expresion.substring(0,i)+" "+c+" "+expresion.substring(i+1);
				i+=2;
			}
			else
				// si no es numero, espacio o un operando debe dar mensaje de error y vuelve a pedir la expresion
				if (!((c == '0') || (c == '1') || (c == '2') || (c == '3') || (c == '4') || (c == '5') || (c == '6') || (c == '7') ||(c == '8') || (c == '9') || (c == ' ') || (c == '.'))){
					System.out.println("--> Error en el ingreso de la expresion <-- ");
					error = true;
				}
		}
	} while (error);
		
	// +-- separar la expresion por espacios y evaluarla utilizando el stack
	expre = expresion.split(" ");
	try{
		for (int i = 0; i < expre.length; i++){
			if (!"".equals(expre[i])){
				char c = expre[i].charAt(0);
				switch(c){
					case '+':  // sumar los ultimos dos numeros metidos al stack y agregar el resultado en el stack
						miStack.push( miStack.pop() + miStack.pop() );
						break;					
					case '-':  // restar los ultimos dos numeros metidos al stack y agregar el resultado en el stack
						numero = miStack.pop();
						miStack.push( miStack.pop() - numero );
						break;
					case '*':  // multiplicar los ultimos dos numeros metidos al stack y agregar el resultado en el stack
						miStack.push( miStack.pop() * miStack.pop() );
						break;
					case '/':  // dividir los ultimos dos numeros metidos al stack y agregar el resultado en el stack
						numero = miStack.pop();
						if (numero == 0)
							System.out.println("--> No se puede dividir entre cero (dicha operacion se ignorara) <--");
						else
							miStack.push( miStack.pop() / numero );
						break;  
					default:   // es un numero, el cual debe agregarse al stack
						numero = Double.valueOf(expre[i]).doubleValue();
						miStack.push(numero);
						break;
				}
			}
		}
		if (miStack.size() == 1)
			System.out.println("\n El Resultado es: "+miStack.pop());
		else
			System.out.println("\n El ingreso de la expresion posee algun termino de mas");
	}
	catch(NullPointerException exception){
			System.out.println("\n --> Verifique el ingreso de la expresion <-- \n");
	}
	
  }
  
	//instrucciones: muestra en pantalla las instrucciones para el programa
	public static void instrucciones(){
            System.out.println("\n+--   BIENVENIDO   ------------------------------+");
            System.out.println("|  Este programa calcula una expresion ingresada |");
            System.out.println("| en formato Postfix. Para hacerlo introduzca    |");
            System.out.println("| la expresion directamente separando los numeros|");	
            System.out.println("| entre si por espacios.                         |");
            System.out.println("+------------------------------------------------+\n");
	}
  
}
